package filesystem.server;

import java.io.File;
import java.io.IOException;
import java.net.Socket;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;

import net.jxta.document.AdvertisementFactory;
import net.jxta.exception.PeerGroupException;
import net.jxta.id.IDFactory;
import net.jxta.logging.Logging;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.PipeService;
import net.jxta.platform.NetworkManager;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.socket.JxtaServerSocket;
import filesystem.util.CloseSocket;


/**
 * Classe principal do servidor.
 * 
 * Inicializa o programa e fica ouvindo conexões.
 */
public class Server{
	public final static String serverPipe = "urn:jxta:uuid-59616261646162614E5047205032503393B5C2F6CA7A41FBB0F890173088E79404"; ///Identificação do pipe do servidor
	
	/**
	 * Inicializa a rede do JXTA
	 * 
	 * @return O grupo de peers
	 * @throws IOException
	 * @throws PeerGroupException
	 */
	public static PeerGroup startNetwork() throws IOException, PeerGroupException {
		NetworkManager manager = new NetworkManager(NetworkManager.ConfigMode.ADHOC,
					"NetServer", new File(new File(".cache"),"Server").toURI() );
		manager.startNetwork();
		return manager.getNetPeerGroup();
	}
	
	/**
	 * Cria um PipeAdvertisement do servidor.
	 * 
	 * @param peergroup O grupo de peers.
	 * @return O próprio PipeAdvertisement.
	 */
	public static PipeAdvertisement createAdvertisement(PeerGroup peergroup){
		try {
			PipeID socketID = ( PipeID ) IDFactory.fromURI(new URI(Server.serverPipe));
			PipeAdvertisement advertisement = (PipeAdvertisement)
	                AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());
			// Seta algumas propriedades
	        advertisement.setPipeID(socketID);
	        advertisement.setType(PipeService.UnicastType);
	        advertisement.setName("Master");
	        return advertisement;
		} catch (URISyntaxException e) {
			e.printStackTrace();
			System.exit(-1);
		}
		return null;
	}
	
	/**
	 * Inicializa o servidor e espera por conexões.
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		System.setProperty(Logging.JXTA_LOGGING_PROPERTY, Level.OFF.toString());
		try {
			PeerGroup peerGroup = Server.startNetwork();
			JxtaServerSocket serverSocket = new JxtaServerSocket(peerGroup, Server.createAdvertisement(peerGroup),1000);
			serverSocket.setSoTimeout(0);
			Runtime.getRuntime().addShutdownHook(new CloseSocket(serverSocket));
			System.out.println("Server started");
			while(true){
				System.out.println("Waiting Connections");
				Socket socket = serverSocket.accept();
				if(socket != null){
					System.out.println("Connection accepted");
					ServerConnection handler = new ServerConnection(socket);
					handler.start();
				}
			}
		} catch (PeerGroupException | IOException e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}
	
}
